const { Question, Answer } = require('../../db/models');
const wait = require('./wait');

let allUsers = new Map();
let allRooms = new Map();

const setupSocketHandlers = (io) => {
  io.on('connection', (socket) => {
    console.log(`User connected ${socket.id}`);
    socket.emit('my_name', socket.id);

    socket.on('create_room', async (data) => {
      try {
        const { user, themeId, roomId } = data;
        socket.join(roomId);
        const questions = await Question.findAll({
          where: { themeId },
        });

        if (!allRooms.get(roomId)) {
          allRooms.set(roomId, {
            status: 'waiting',
            roomName: roomId,
            creator: user,
            players: [user],
            questions: questions,
            currentQuestionId: 0,
            themeId: themeId,
            currentAnswers: [],
          });
        } else {
          allRooms.get(roomId).players.push(user);
        }

        socket.to(roomId).emit('room_users', allRooms.get(roomId));
        socket.emit('room_users', allRooms.get(roomId));
      } catch (error) {
        console.error('An error occurred:', error);
      }
    });
    socket.on('join_room', (data) => {
      try {
        const { user, roomName } = data;
        if (
          allRooms.get(roomName).status === 'waiting' &&
          allRooms.get(roomName).players.length <= 5
        ) {
          socket.join(roomName);
          allRooms.get(roomName).players.push(user);
          socket.to(roomName).emit('room_users', allRooms.get(roomName));
          socket.emit('room_users', allRooms.get(roomName));
        }
      } catch (error) {
        console.error('An error occurred:', error);
      }
    });

    socket.on('redirect', async (data) => {
      try {
        const { roomName } = data;
        allRooms.get(roomName).status = 'start';
        const { currentQuestionId } = allRooms.get(roomName);
        const questions = allRooms.get(roomName).questions;
        const currentQuestion = questions[currentQuestionId];
        const currentAnswers = await Answer.findAll({
          where: { questionId: currentQuestion.id },
        });
        allRooms.get(roomName).currentAnswers = currentAnswers;

        socket.to(roomName).emit('start', allRooms.get(roomName));
        for (let index = 0; index < questions.length - 1; index++) {
          await wait(16000);

          allRooms.get(roomName).currentQuestionId += 1;
          const { currentQuestionId } = allRooms.get(roomName);

          const nextQuestion = allRooms.get(roomName).questions[currentQuestionId];

          const nextAnswers = await Answer.findAll({
            where: { questionId: nextQuestion.id },
          });
          allRooms.get(roomName).currentAnswers = nextAnswers;
          socket.to(roomName).emit('nextquestion', allRooms.get(roomName));
        }
        await wait(16000);
        socket.to(roomName).emit('results', allRooms.get(roomName));
      } catch (error) {
        console.error('An error occurred:', error);
      }
    });

    socket.on('answer', (data) => {
      try {
        const { id, userId, room } = data;
        const { currentQuestionId } = allRooms.get(room);
        const currentQuestion = allRooms.get(room).questions[currentQuestionId];
        if (id === currentQuestion.rightAnswer) {
          allRooms.get(room).players.find((pl) => pl.id === userId).score += 1;
        }
        socket.to(room).emit('newScore', allRooms.get(room));
      } catch (error) {
        console.error('An error occurred:', error);
      }
    });

    socket.on('disconnect', () => {
      try {
        allUsers.delete(socket.id);
        console.log('Осталось в комнате', allUsers);
      } catch (error) {
        console.error('An error occurred:', error);
      }
    });
  });
};

module.exports = setupSocketHandlers;
